/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package SearchEngineQueryNew;

import ApacheClient.ApacheClient;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import Parser.*;

/**
 *
 * @author Chris
 */
public class YahooQuery {
    private ApacheClient client = new ApacheClient();
    private int queryDelay = 0;
    private int pageDelay = 0;
    private int pDelayRange = 0;
    private int qDelayRange = 0;

    public YahooQuery() {

    }

    public YahooQuery(int queryDelay, int pageDelay) {
        this.queryDelay = queryDelay;
        this.pageDelay = pageDelay;
    }

    public YahooQuery(int queryDelay, int pageDelay, int qDR, int pDR) {
        this.queryDelay = queryDelay;
        this.pageDelay = pageDelay;
        qDelayRange = qDR;
        pDelayRange = pDR;
    }

    protected void pageDelay() throws Exception {
        // A pointless delay
        Thread.sleep(pageDelay + (int) (Math.random() * pDelayRange));
    }

    protected void queryDelay() throws Exception {
        // A pointless delay
        Thread.sleep(queryDelay + (int) (Math.random() * qDelayRange));
    }

    // Replace unacceptable entries with valid ones
    protected String fixQuery(String query) {
        String result;

        result = query;
        result = result.replace(" ", "+");
        result = result.replace("%", "%25");

        return result;
    }

    public InputStream submitQuery(String query, int page) throws IOException {
        String prefix = "http://search.yahoo.com/search?p=";
        String suffix = "";
        String urltext;

        query = fixQuery(query);

        if (page <= 1)
            urltext = prefix + query + "&toggle=1&cop=mss&ei=UTF-8&fr=yfp-t-701" + suffix;
        else
            urltext = prefix + query + "&toggle=1&cop=mss&ei=UTF-8&fr=yfp-t-701&xargs=0&pstart=1" + ((page - 2) * 10 + 1) + "&b=" + ((page - 1) * 10 + 1) + "&" + suffix;

        return client.getPage(urltext);
    }

    public void dumpQuery(String query, int page) throws Exception {
        InputStream content = submitQuery(query, page);
        BufferedReader read = new BufferedReader(new InputStreamReader(content));

        String line;

        line = read.readLine();
        while (line != null) {
            System.out.println(line);
            line = read.readLine();
        }

        read.close();
    }

    public ArrayList<SearchResult> getResults(String query, int page) throws Exception {
        ArrayList<SearchResult> result = new ArrayList<SearchResult>();
        InputStream content = submitQuery(query, page);
        BufferedReader read = new BufferedReader(new InputStreamReader(content));
        ParseTree tree = new ParseTree(read);
        Token[] tokens = tree.getTokens();
        int pos;
        int pos2;
        int pos3;

        String url;
        String summary;
        String att;

        // Get the <a ...> tags
        pos = tree.findNextTag(0, Token.A);
        while (pos >= 0) {
            att = tokens[pos].valueOfAtt("class");
            if (att != null && att.equalsIgnoreCase("yschttl spt")) {
                url = tokens[pos].valueOfAtt("href");

                // Yahoo wraps the links, we need to unwrap it
                url = url.substring(url.lastIndexOf("**http%3a//") + 11);
                
                pos2 = tree.findNextTag(pos + 1, Token.DIV);
                summary = tree.getAllTextInsideToken(pos2).toString();
                result.add(new SearchResult(url, summary));
            }
            pos = tree.findNextTag(pos + 1, Token.A);
        }

        read.close();

        return result;
    }

    public ArrayList<SearchResult> getResults(String query, int startPage, int endPage) throws Exception {
        ArrayList<SearchResult> result = new ArrayList<SearchResult>();

        for (int c = startPage; c <= endPage; c++) {
            result.addAll(getResults(query, c));
        }

        return result;
    }

    public ArrayList<SearchResult> getResultsWithDelay(String query, int startPage, int endPage) throws Exception {
        ArrayList<SearchResult> result = new ArrayList<SearchResult>();

        for (int c = startPage; c <= endPage; c++) {
            result.addAll(getResults(query, c));
            pageDelay();
        }

        return result;
    }
}
